package services

import (
	"backend/log"
	"backend/models"

	"go.uber.org/zap"
	"gorm.io/gorm"
)

type UserService struct {
	db *gorm.DB
}

type PageInfo struct {
	Size  int `json:"size"`
	Page  int `json:"page"`
	Total int `json:"total"`
}

func NewUserService(db *gorm.DB) *UserService {
	return &UserService{db: db}
}

func (s *UserService) CreateUser(user *models.User) error {
	return s.db.Create(user).Error
}

func (s *UserService) UpdateUser(uuid string, user *models.User) error {
	err := s.db.Where("id = ?", uuid).Updates(user)
	if err.Error != nil {
		log.Logger.Error("更新用户失败", zap.Error(err.Error))
		return err.Error
	}
	return nil
}

func (s *UserService) GetUser(uuid string) (*models.User, error) {
	var user models.User
	err := s.db.Where("id = ?", uuid).First(&user).Error
	if err != nil {
		log.Logger.Error("获取用户失败", zap.Error(err))
		return nil, err
	}
	return &user, nil
}

func (s *UserService) DeleteUser(uuid string) error {
	err := s.db.Where("id = ?", uuid).Delete(&models.User{}).Error
	if err != nil {
		log.Logger.Error("删除用户失败", zap.Error(err))
		return err
	}
	return nil
}

func (s *UserService) DisableUser(ids []uint, disable bool) error {
	var user models.User
	if err := s.db.Model(&user).Where("id in ? ", ids).Update("status", disable).Error; err != nil {
		return err
	}
	return nil
}

func (s *UserService) GetUserList(page *models.PageInfo, user *models.User) ([]*models.User, int64, error) {
	var users []*models.User
	var total int64

	query := s.db.Model(&models.User{})
	if user.Email != "" {
		query = query.Where("email = ?", user.Email)
	}

	if user.Username != "" {
		query = query.Where("username = ?", user.Username)
	}

	// 获取符合条件的总数
	if err := query.Count(&total).Error; err != nil {
		log.Logger.Error("获取用户总数失败", zap.Error(err))
		return nil, 0, err
	}

	result := query.Order("created_at DESC").Limit(page.Size).Offset((page.Page - 1) * page.Size).Find(&users)
	if result.Error != nil {
		log.Logger.Error("获取用户失败", zap.Error(result.Error))
		return nil, 0, result.Error
	}

	return users, total, nil
}

func (s *UserService) Login(user *models.User) error {
	err := s.db.Where("email = ? and password = ?", user.Email, user.Password).First(user).Error
	if err != nil {
		log.Logger.Error("登录失败", zap.Error(err))
		return err
	}
	return nil
}

func (s *UserService) GetUserBindGroupList(userID uint, p *models.PageInfo, m *models.Group) ([]models.Group, error) {
	var user models.User

	// 查询用户并预加载与其关联的组信息
	err := s.db.Model(&models.User{}).Preload("Groups", func(db *gorm.DB) *gorm.DB {
		// 这里可以添加过滤条件，比如按 Group 的 Name 或 Type 进行过滤
		if m.Name != "" {
			db = db.Where("name = ?", m.Name)
		}
		return db
	}).First(&user, userID).Error
	if err != nil {
		return nil, err
	}

	// 提取用户关联的组列表
	groups := user.Groups

	return groups, nil
}

func (s *UserService) BindUserGroup(userId uint, groupIds []uint, action string) error {
	var user models.User
	var groups []models.Group

	// 查询用户
	if err := s.db.First(&user, userId).Error; err != nil {
		return err
	}

	// 根据 groupIDs 查询所有组
	if err := s.db.Where("id IN ?", groupIds).Find(&groups).Error; err != nil {
		return err
	}

	if action == "bind" {
		if err := s.db.Model(&user).Association("Groups").Append(&groups); err != nil {
			return err
		}
	} else if action == "ubind" {
		if err := s.db.Model(&user).Association("Groups").Delete(&groups); err != nil {
			return err
		}
	}
	// 通过 ORM 的 Association 方法将用户与多个组进行关联

	return nil
}

func (u *UserService) GetUserPermission(email string) (*models.User, error) {
	// 查询用户及其所属组
	var user models.User
	err := u.db.Preload("Groups.Roles.Permissions").Where("email = ?", email).First(&user).Error
	if err != nil {
		return nil, err
	}
	return &user, nil

}
